{
    _CP_.OPTIONS_HANDLER
        .set('value4data', {
            [Etype.string]: U.F.fn.obj,
            [Etype.boolean]: U.F.fn.obj,
            [Etype.number]: U.F.fn.obj,
            [Etype.null]: U.F.fn.obj,
            [Etype.array]: U.F.fn.obj,
        })
        .set('data', {
            [Etype.string]: U.F.fn.obj,
            [Etype.boolean]: U.F.fn.obj,
            [Etype.number]: U.F.fn.obj,
            [Etype.null]: U.F.fn.obj,
            [Etype.array]: U.F.fn.obj,
        })
        .set('url', {
            [Etype.string]: U.F.fn.obj,
            [Etype.function]: U.F.fn.obj,
        })
        .set('dataTextKey', {
            [Etype.string]: U.F.fn.obj,
        })
        .set('dataValueKey', {
            [Etype.string]: U.F.fn.obj,
        })
        .set('multiple', {
            [Etype.boolean]: U.F.fn.obj,
        });
}

/**
 * 数据控件注解
 * @param target 目标类型
 */
function ACdata(target: any) {
    if (!U.isSubClass(_CDVP_, target)) { return; }

    // 默认值
    const original_options_default = target.prototype.options_default;
    target.prototype.options_default = function (this: _CDVP_<any>) {
        const defaultOptions = original_options_default.call(this);

        U.O.setDefaultValue(defaultOptions, 'dataTextKey', 'text');
        U.O.setDefaultValue(defaultOptions, 'dataValueKey', 'value');
        U.O.setDefaultValue(defaultOptions, 'multiple', false);

        return defaultOptions;
    };

    // 处理器
    const original_options_handlers = target.prototype.options_handlers;
    target.prototype.options_handlers = function (this: _CDVP_<any>) {
        const options_handlers = original_options_handlers.call(this);

        U.O.setDefaultValue(options_handlers, 'value', _CP_.OPTIONS_HANDLER.get('value4data'));
        U.O.setDefaultValue(options_handlers, 'data', _CP_.OPTIONS_HANDLER.get('data'));
        U.O.setDefaultValue(options_handlers, 'url', _CP_.OPTIONS_HANDLER.get('url'));
        U.O.setDefaultValue(options_handlers, 'dataTextKey', _CP_.OPTIONS_HANDLER.get('dataTextKey'));
        U.O.setDefaultValue(options_handlers, 'dataValueKey', _CP_.OPTIONS_HANDLER.get('dataValueKey'));
        U.O.setDefaultValue(options_handlers, 'multiple', _CP_.OPTIONS_HANDLER.get('multiple'));

        return options_handlers;
    };

    // 重载配置
    const original_overloading_mapping = target.prototype.overloading_mapping;
    target.prototype.overloading_mapping = function (this: _CDVP_<any>, mapping: Toption_key_to_types_mapping<Toptions_DATA>) {
        const overloading_mapping = original_overloading_mapping.call(this, mapping);

        overloading_mapping.push([
            { key: 'data', types: [Etype.array] },
        ]);

        return overloading_mapping;
    };

    // 校验
    const original_options_checker = target.prototype.options_checker;
    target.prototype.options_checker = function (this: _CDVP_<any>, options: Toptions_DATA) {
        original_options_checker.call(this, options);

        U.O.setDefaultValue(options, 'value', DEFAULT);

        if (Object.prototype.hasOwnProperty.call(options, 'data')) {
            if (!Array.isArray(options.data)) {
                options.data = [
                    {
                        [options.dataTextKey as string]: options.data!,
                        [options.dataValueKey as string]: options.data!
                    }
                ];
            }
        } else {
            if (Object.prototype.hasOwnProperty.call(options, 'url')) {
            } else {
                options.data = [];
            }
        }
    };

    const render_data = function (this: _CDVP_<any>, data: Array<Toptions_DATA$dataI>) {
        if (!Array.isArray(data)) { return; }// 无数据，不渲染。

        const dataTextKey = this.options.dataTextKey;
        const dataValueKey = this.options.dataValueKey;

        data.forEach((dataI: any) => {
            if (!U.is(Etype.obj, dataI)) {
                dataI = {
                    [dataTextKey as string]: dataI,
                    [dataValueKey as string]: dataI,
                };
            }

            let text = (dataI as any)[this.options.dataTextKey!];
            switch (U.typeof(text)) {
                case Etype.string:
                    break;
                case Etype.boolean:
                case Etype.number:
                case Etype.null:
                    text = String(text);
                    break;
                default:
                    text = '';
                    break;
            }
            let value = (dataI as any)[this.options.dataValueKey!];

            // 渲染数据元素
            const ele_item = this.item_render(dataI, text, value);

            // 加入缓存
            this.items.push(ele_item);

            // 绑定数据
            (ele_item as any).dataValue = value;
        });

        this.setValue(this.options.value);
    };

    // 初始化
    const original_initializer = target.prototype.initializer;
    target.prototype.initializer = function (this: _CDVP_<any>) {
        original_initializer.call(this);

        this.items = [];

        if (Object.prototype.hasOwnProperty.call(this.options, 'data')) {
            render_data.call(this, this.options.data);
        } else {
            const url = U.is(Etype.function, this.options.url) ? this.options.url.call(this.options) : this.options.url;
            U.GET(url).then(data => {
                // @ts-ignore Argument of type 'unknown' is not assignable to parameter of type 'Toptions_DATA$dataI[]'.ts(2345)
                render_data.call(this, data);
            });
        }
    };
}
